
// IDEAS:
//  battle:
// 	archers can stand on walls?
//
// 	multiforce:
// 	maximum of N forces can be at single location at the same time
// 	when engaging multiple forces, they get to spend an actuon to swap and end turn
// 	swapped away fields are frozen, do not update
// 	allies share the turn, and can engage together (join a battle like a game lobby)
//
// multiplayer etiquette
//  if opponent doesn't make a move in N time you are allowed to warn them
//  if still no move in M time you are allowed to end their turn
//  if no match in N turns, again can warn
//  if no match in M turns, can declare a win
//  with option to make this automatic
//  also another player can join the game instead of kicked player, and and and also multiplayer games can be saved and loaded, yep


#include "simple/support/tuple_utils/apply_for.hpp" // apply_to

#include "game.h"
#include "ui.h"

// timid weakling -- brute forces
// shallow ignoramus -- neural net
// clumsy doofus -- clever hand-coded strategies
// Random Barimen -- just random moves
struct faker {
	game::world& world;
	std::optional<game::action> action() {return std::nullopt;}
};

int main(int argc, char const* argv[])
{
	const auto peeps = game::faction_id{0};

	const auto red = game::color{1};
	const auto green = game::color{2};
	const auto yellow = game::color{3};

	constexpr game::unsigned2 small_field_size {7u,7u};
	const auto small_field = game::field_t(small_field_size.x() * small_field_size.y(), std::nullopt);

	game::world world
	{
		// guys
		{
			// sword
			{
				peeps, game::unsigned2::one(), {10},
				{2, 1, 2}
			},
			// bow
			{
				peeps, game::unsigned2::one(), {15},
				{1, 1, 1}
			},
			// spear
			{
				peeps, game::unsigned2::one(), {30},
				{1, 3, 3}
			},
		},

		// forces
		{
			{
				{ {game::force::counter{50},red}, {game::force::counter{35},green}, {game::force::counter{25},yellow} },
				std::nullopt,
				21,
				50
			},
			{
				{ {game::force::counter{50},red}, {game::force::counter{35},green}, {game::force::counter{25},yellow} },
				std::nullopt,
				21,
				50
			},
		},

	};

	auto take_back = [](auto& vec)
	{
		auto i = vec.end() - 1;
		auto el = std::move(*i);
		vec.erase(i);
		return el;
	};

	ui ui{world};
	ui.intro("Feeble & Mundane: Scatter The Cowards");

	ui.battle(world.current_battle.emplace(game::battle
		{
			small_field_size,
			{small_field, small_field},
			{take_back(world.forces),take_back(world.forces)}
		}
	));

	world.reinforce();
	world.end_turn();
	world.reinforce();
	world.end_turn();

	const auto& spawned = world.spawn();
	if(world.valid_field_position(spawned))
		ui.spawned(spawned);
	// else notify player there was no place to spawn

	faker opponent{world};
	auto order = std::tie(ui, opponent);

	while(ui.loop())
	{
		if(world.current_battle)
		{
			auto action = simple::support::apply_to(world.current_battle->turn % 2, [](auto& player){
				return player.action();
			}, order);
			if(action)
				world.perform(*action);
		}
		world.updates.erase(world.updates.begin(), world.updates.begin() +
			ui.update(world.updates));
	}

	return 0;
}
